#include "textura.h"
#include "texcomprimida.h"
#include "iobmp.h"
#include <GL/glut.h>
#include <iostream>
using namespace std;

class Skybox{
private:
    Textura* tex_daylight;
    Textura* tex_night;
    IObmp* io;
    float distancia;
    GLuint dl_handle_daylight;
    GLuint dl_handle_night;
    bool daylight;
public:
    Skybox(float distancia):distancia(distancia), daylight(true){
        io = new IObmp();
        daylight = true;
        Texels& texelsDay = io->cargarBMP("cielocub.bmp");
        tex_daylight = new TexturaComprimida(texelsDay);
        Texels& texelsNight = io->cargarBMP("night.bmp");
        tex_night = new TexturaComprimida(texelsNight);

        delete &texelsDay;
        delete &texelsNight;

        dl_handle_daylight = glGenLists(1);
        dl_handle_night = glGenLists(1);
        glNewList(dl_handle_daylight, GL_COMPILE);
		    initDaylight();
	    glEndList();
	    glNewList(dl_handle_night, GL_COMPILE);
	        initNight();
	    glEndList();
    }

    void switchTime(){
		if (daylight){
			daylight = false;
			glEnable(GL_LIGHT1);
			glDisable(GL_LIGHT0);
			GLfloat lmodel_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
			glutPostRedisplay();
		}
		else{
			daylight = true;
			glEnable(GL_LIGHT0);
			glDisable(GL_LIGHT1);
			glutPostRedisplay();
		}
    }

    virtual ~Skybox(){
        delete io;
        delete tex_daylight;
        delete tex_night;
    }

    void dibujar(){
    	if(daylight){
    		glCallList(dl_handle_daylight);
    	}
    	else {
    		GLfloat mat_emission[] = {0.1, 0.1, 0.1, 0.5};
    		glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
    		glCallList(dl_handle_night);
    	}
    }

    void setDaylightIllum(){
    	// Luz del sol
    	float light_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
    	float light_position[3] = {0.0f, 0.0f, 15.0f};
    	float light_ambient[4] = {0.99f, 0.99f, 0.99f, 1.0f};

    	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color);
    	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    	GLfloat lmodel_ambient[] = { 0.99, 0.99, 0.99, 1.0 };
    	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
    	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
    	glEnable(GL_LIGHT0);
    	glEnable(GL_LIGHTING);

    	// Luz de la luna
    	float light_color1[4] = {1.0f, 1.0f, 1.0f, 1.0f};
    	float light_position1[4] = {0.0f, 0.0f, 0.0f, 5.0f};
    	float light_ambient1[4] = {0.9f, 0.9f, 0.9f, 1.0f};
    	float spot_dir1[4] = {-1.0f, -1.0f, -0.0f};
    	float spot_cutoff1[1] = {25.0f};

    	glLightfv(GL_LIGHT1, GL_DIFFUSE, light_color1);
    	glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient1);
    	glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
    	glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_dir1);
    	glLightfv(GL_LIGHT1, GL_SPOT_CUTOFF, spot_cutoff1);
    	glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.0);
    	glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0);
    	glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0);
    	glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 1.0);
    }

    void initDaylight(){
        glPushMatrix();
        glScalef(distancia,distancia,distancia);
        glTranslatef(-0.5,-0.5,-0.5);
        float norm = 0.57735;
        tex_daylight->enlazar();
        glBegin(GL_QUADS);
            
            //inferior
            //glTexCoord2f(0.0,0.0);
            //glTexCoord2f(0.5*0.2,1.0*0.2);
            glTexCoord2f(0.5*0.2,1*0.2);
            glNormal3f(norm,norm,norm);
            glVertex3f(0.0,0.0,0.0);
            //glTexCoord2f(0.5*0.2,0.66666666*0.2);
            //glTexCoord2f(0.0,0.2);
            glTexCoord2f(0.5*0.2,0);
            glNormal3f(-norm,norm,norm);
            glVertex3f(1.0,0.0,0.0);
            //glTexCoord2f(0.25*0.2,0.66666666*0.2);
            //glTexCoord2f(0.2,0.2);
            glTexCoord2f(0.66666666*0.2,0);
            glNormal3f(-norm,-norm,norm);
            glVertex3f(1.0,1.0,0.0);
            //glTexCoord2f(0.25*0.2,1.0*0.2);
            //glTexCoord2f(0.2,0.0);
            glTexCoord2f(0.66666666*0.2,1*0.2);
            glNormal3f(norm,-norm,norm);
            glVertex3f(0.0,1.0,0.0);
            
            //cerca
            //glTexCoord2f(0.0,0.0);
            //glTexCoord2f(0.25*0.2,0.66666666*0.2);
            glTexCoord2f(0.833333333*0.2,1*0.2);
            glNormal3f(-norm,-norm,norm);
            glVertex3f(1.0,1.0,0.0);
            //glTexCoord2f(0.5*0.2,0.66666666*0.2);
            //glTexCoord2f(0.0,1.0);
            glTexCoord2f(1*0.2,1*0.2);
            glNormal3f(-norm,norm,norm);
            glVertex3f(1.0,0.0,0.0);
            //glTexCoord2f(0.5*0.2,0.33333333*0.2);
            //glTexCoord2f(1.0,1.0);
            glTexCoord2f(1*0.2,0*0.2);
            glNormal3f(-norm,norm,-norm);
            glVertex3f(1.0,0.0,1.0);
            //glTexCoord2f(0.25*0.2,0.333333333*0.2);
            //glTexCoord2f(1.0,0.0);
            glTexCoord2f(0.833333333*0.2,0*0.2);
            glNormal3f(-norm,-norm,-norm);
            glVertex3f(1.0,1.0,1.0);

            //arriba
            //glTexCoord2f(0.25,1.0); //hasta aca
            //glTexCoord2f(0.0,0.0);
            glTexCoord2f(0.33333333*0.2,0*0.2);
            glNormal3f(-norm,norm,-norm);
            glVertex3f(1.0,0.0,1.0);  // (1,0,1)
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(0.0,1.0);
            glTexCoord2f(0.33333333*0.2,1.0*0.2);
            glNormal3f(norm,norm,-norm);
            glVertex3f(0.0,0.0,1.0); // (0,0,1)
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(1.0,1.0);
            glTexCoord2f(0.5*0.2,1*0.2);
            glNormal3f(norm,-norm,-norm);
            glVertex3f(0.0,1.0,1.0); // (0,1,1)
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(1.0,0.0);
            glTexCoord2f(0.5*0.2,0.0*0.2);
            glNormal3f(-norm,-norm,-norm);
            glVertex3f(1.0,1.0,1.0); // (1,1,1)

            //lejos
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(0.0,0.0);
            glTexCoord2f(0.83333333*0.2,0);
            glNormal3f(norm,-norm,-norm);
            glVertex3f(0.0,1.0,1.0);
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(0.0,1.0);
            glTexCoord2f(0.6666666*0.2,0);
            glNormal3f(norm,norm,-norm);
            glVertex3f(0.0,0.0,1.0);
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(1.0,1.0);
            glTexCoord2f(0.66666666*0.2,1*0.2);
            glNormal3f(norm,norm,norm);
            glVertex3f(0.0,0.0,0.0);
            //glTexCoord2f(0.25,1.0);
            //glTexCoord2f(1.0,0.0);
            glTexCoord2f(0.83333333*0.2,1*0.2);
            glNormal3f(norm,-norm,norm);
            glVertex3f(0.0,1.0,0.0);
            
            //izquierda
            //glTexCoord2f(0.0,0.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.16666666*0.2,0*0.2);
            glNormal3f(-norm,norm,-norm);
            glVertex3f(1.0,0.0,1.0);
            //glTexCoord2f(0.0,1.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.16666666*0.2,1*0.2);
            glNormal3f(-norm,norm,norm);
            glVertex3f(1.0,0.0,0.0);
            //glTexCoord2f(1.0,1.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.33333333*0.2,1*0.2);
            glNormal3f(norm,norm,norm);
            glVertex3f(0.0,0.0,0.0);
            //glTexCoord2f(1.0,0.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.33333333*0.2,0*0.2);
            glNormal3f(norm,norm,-norm);
            glVertex3f(0.0,0.0,1.0);
            
            //derecha
            //glTexCoord2f(0,1.0);
            glTexCoord2f(0*0.2,0.0);
            glNormal3f(norm,-norm,-norm);
            glVertex3f(0.0,1.0,1.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0*0.2,1.0*0.2);
            glNormal3f(norm,-norm,norm);
            glVertex3f(0.0,1.0,0.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.16666666*0.2,1.0*0.2);
            glNormal3f(-norm,-norm,norm);
            glVertex3f(1.0,1.0,0.0);
            //glTexCoord2f(0.25,1.0);
            glTexCoord2f(0.16666666*0.2,0.0*0.2);
            glNormal3f(-norm,-norm,-norm);
            glVertex3f(1.0,1.0,1.0);
            
        glEnd();
        tex_daylight->desenlazar();
        glPopMatrix();
    }

    void initNight(){
    	glPushMatrix();
    	glScalef(distancia,distancia,distancia);
    	glTranslatef(-0.5,-0.5,-0.5);
    	float norm = 0.57735;
    	tex_night->enlazar();
    	glBegin(GL_QUADS);
        //inferior
        //glTexCoord2f(0.0,0.0);
        //glTexCoord2f(0.5*0.2,1.0*0.2);
        glTexCoord2f(0.5*0.2,1*0.2);
        glNormal3f(norm,norm,norm);
        glVertex3f(0.0,0.0,0.0);
        //glTexCoord2f(0.5*0.2,0.66666666*0.2);
        //glTexCoord2f(0.0,0.2);
        glTexCoord2f(0.5*0.2,0);
        glNormal3f(-norm,norm,norm);
        glVertex3f(1.0,0.0,0.0);
        //glTexCoord2f(0.25*0.2,0.66666666*0.2);
        //glTexCoord2f(0.2,0.2);
        glTexCoord2f(0.66666666*0.2,0);
        glNormal3f(-norm,-norm,norm);
        glVertex3f(1.0,1.0,0.0);
        //glTexCoord2f(0.25*0.2,1.0*0.2);
        //glTexCoord2f(0.2,0.0);
        glTexCoord2f(0.66666666*0.2,1*0.2);
        glNormal3f(norm,-norm,norm);
        glVertex3f(0.0,1.0,0.0);

        //cerca
        //glTexCoord2f(0.0,0.0);
        //glTexCoord2f(0.25*0.2,0.66666666*0.2);
        glTexCoord2f(0.833333333*0.2,1*0.2);
        glNormal3f(-norm,-norm,norm);
        glVertex3f(1.0,1.0,0.0);
        //glTexCoord2f(0.5*0.2,0.66666666*0.2);
        //glTexCoord2f(0.0,1.0);
        glTexCoord2f(1*0.2,1*0.2);
        glNormal3f(-norm,norm,norm);
        glVertex3f(1.0,0.0,0.0);
        //glTexCoord2f(0.5*0.2,0.33333333*0.2);
        //glTexCoord2f(1.0,1.0);
        glTexCoord2f(1*0.2,0*0.2);
        glNormal3f(-norm,norm,-norm);
        glVertex3f(1.0,0.0,1.0);
        //glTexCoord2f(0.25*0.2,0.333333333*0.2);
        //glTexCoord2f(1.0,0.0);
        glTexCoord2f(0.833333333*0.2,0*0.2);
        glNormal3f(-norm,-norm,-norm);
        glVertex3f(1.0,1.0,1.0);

        //arriba
        //glTexCoord2f(0.25,1.0); //hasta aca
        //glTexCoord2f(0.0,0.0);
        glTexCoord2f(0.33333333*0.2,0*0.2);
        glNormal3f(-norm,norm,-norm);
        glVertex3f(1.0,0.0,1.0);  // (1,0,1)
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(0.0,1.0);
        glTexCoord2f(0.33333333*0.2,1.0*0.2);
        glNormal3f(norm,norm,-norm);
        glVertex3f(0.0,0.0,1.0); // (0,0,1)
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(1.0,1.0);
        glTexCoord2f(0.5*0.2,1*0.2);
        glNormal3f(norm,-norm,-norm);
        glVertex3f(0.0,1.0,1.0); // (0,1,1)
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(1.0,0.0);
        glTexCoord2f(0.5*0.2,0.0*0.2);
        glNormal3f(-norm,-norm,-norm);
        glVertex3f(1.0,1.0,1.0); // (1,1,1)

        //lejos
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(0.0,0.0);
        glTexCoord2f(0.83333333*0.2,0);
        glNormal3f(norm,-norm,-norm);
        glVertex3f(0.0,1.0,1.0);
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(0.0,1.0);
        glTexCoord2f(0.6666666*0.2,0);
        glNormal3f(norm,norm,-norm);
        glVertex3f(0.0,0.0,1.0);
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(1.0,1.0);
        glTexCoord2f(0.66666666*0.2,1*0.2);
        glNormal3f(norm,norm,norm);
        glVertex3f(0.0,0.0,0.0);
        //glTexCoord2f(0.25,1.0);
        //glTexCoord2f(1.0,0.0);
        glTexCoord2f(0.83333333*0.2,1*0.2);
        glNormal3f(norm,-norm,norm);
        glVertex3f(0.0,1.0,0.0);

        //izquierda
        //glTexCoord2f(0.0,0.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.16666666*0.2,0*0.2);
        glNormal3f(-norm,norm,-norm);
        glVertex3f(1.0,0.0,1.0);
        //glTexCoord2f(0.0,1.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.16666666*0.2,1*0.2);
        glNormal3f(-norm,norm,norm);
        glVertex3f(1.0,0.0,0.0);
        //glTexCoord2f(1.0,1.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.33333333*0.2,1*0.2);
        glNormal3f(norm,norm,norm);
        glVertex3f(0.0,0.0,0.0);
        //glTexCoord2f(1.0,0.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.33333333*0.2,0*0.2);
        glNormal3f(norm,norm,-norm);
        glVertex3f(0.0,0.0,1.0);

        //derecha
        //glTexCoord2f(0,1.0);
        glTexCoord2f(0*0.2,0.0);
        glNormal3f(norm,-norm,-norm);
        glVertex3f(0.0,1.0,1.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0*0.2,1.0*0.2);
        glNormal3f(norm,-norm,norm);
        glVertex3f(0.0,1.0,0.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.16666666*0.2,1.0*0.2);
        glNormal3f(-norm,-norm,norm);
        glVertex3f(1.0,1.0,0.0);
        //glTexCoord2f(0.25,1.0);
        glTexCoord2f(0.16666666*0.2,0.0*0.2);
        glNormal3f(-norm,-norm,-norm);
        glVertex3f(1.0,1.0,1.0);
    	  glEnd();
    	  tex_night->desenlazar();
    	  glPopMatrix();
    }
};
